package cn.sangedon.review.analysis.strategy.specific;

import cn.sangedon.review.analysis.constant.StrategyEnum;
import cn.sangedon.review.analysis.utils.CheckUtil;
import cn.sangedon.review.common.constant.StockConstant;
import cn.sangedon.review.common.domain.analysis.StockStrategy;
import cn.sangedon.review.common.domain.analysis.StockStrategyResult;
import cn.sangedon.review.common.domain.data.StockDayInfo;
import cn.sangedon.review.common.query.data.StockDayInfoQuery;
import cn.sangedon.review.common.service.data.StockDayInfoService;
import cn.sangedon.review.common.service.data.TradingDateService;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Component;

/**
 * 连续上涨，缩量，且后一个交易日涨幅大于前一个交易日
 */
@Slf4j
@Component
public class RiseShrinkRedStrategy extends AbstractScheduleTradeStrategy {
    @DubboReference
    private StockDayInfoService stockDayInfoService;

    @DubboReference
    private TradingDateService tradingDateService;

    @Override
    public void runJob(List<StockStrategy> strategyList) {
        strategyList.stream().filter(e -> e.getStrategyName().equals(StrategyEnum.RISE_SHRINK_RED.getName())).findFirst().ifPresent(e -> {
            addSchedule(e);
        });
    }

    @Override
    public void execute() {
        log.info("开始执行上涨缩量红策略");
        String tradeDate = stockDayInfoService.getLatestDate();
        execute(tradeDate);
    }

    /**
     * 获取某个交易日符合上涨缩量红策略的股票
     * 上涨缩量红：
     * 成交量逐渐变小，但是股价逐步上升，且后一个交易日股价涨幅大于前一个交易日
     *
     * @param tradeDate 交易日，当前交易日符合上涨缩量红策略的股票
     */
    public void execute(String tradeDate) {
        String preTradeDate = tradingDateService.getTradeDateAgo(tradeDate, 1);
        StockDayInfoQuery query = new StockDayInfoQuery();
        query.setStartTime(preTradeDate);
        query.setEndTime(tradeDate);
        List<StockDayInfo> dayInfos = stockDayInfoService.getStockDayInfos(query);

        List<StockStrategyResult> list = new ArrayList<>();
        Map<String, List<StockDayInfo>> listMap = dayInfos.stream().filter(e -> filterMajor(e))
                                                          .collect(Collectors.groupingBy(StockDayInfo::getCode));
        for (Entry<String, List<StockDayInfo>> entry : listMap.entrySet()) {
            List<StockDayInfo> infos = entry.getValue();
            if (infos.size() < 2) {
                continue;
            }

            StockDayInfo today = infos.get(0);
            StockDayInfo yestoday = infos.get(1);
            if (CheckUtil.riseShrinkRed(today, yestoday)) {
                StockStrategyResult strategyResult = new StockStrategyResult();
                strategyResult.setStrategyId(stockStrategy.getId());
                strategyResult.setStrategyName(stockStrategy.getStrategyName());
                strategyResult.setStockName(today.getName());
                strategyResult.setStockCode(today.getCode());
                strategyResult.setTradingDate(today.getTradingDate());
                list.add(strategyResult);
            }
        }
        stockStrategyResultService.saveBatch(list);
        log.info("符合上涨缩量红要求的股票数量:{}", list.size());
    }

    private boolean filterMajor(StockDayInfo stockDayInfo) {
        if (stockDayInfo.getCode().startsWith(StockConstant.SH_STOCK_CODE_PREFIX) ||
            stockDayInfo.getCode().startsWith(StockConstant.SZ_STOCK_CODE_PREFIX)) {
            return true;
        }
        return false;
    }
}
